<?php
/**
 * +--------------------------------------------------------------
 * | eLuoPHP
 * +--------------------------------------------------------------
 * | Copyright (c) 2016-2018 http://qxwoo.cn All rights reserved.
 * +--------------------------------------------------------------
 * | y139w [y139w@163.com]
 * +--------------------------------------------------------------
 * | Session处理类文件
 * +--------------------------------------------------------------
 */

namespace luo;

class Session
{

    /**
     * Session对象
     * @var Session
     */
    private static $_instance;

    /**
     * 存储session值
     * @var array
     */
    private static $session;

    /**
     * 构造
     * Session constructor.
     */
    private function __construct()
    {
        // 是否开启了session，如果没有开启session，把session开启
        if(session_status() !== PHP_SESSION_ACTIVE && PHP_SAPI !== 'cli'){
            session_start();
        }
        self::$session = isset($_SESSION[md5('luoPhp')]) ? $_SESSION[md5('luoPhp')] : null;

    }

    /**
     * 防止被克隆
     */
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * 静态方法调用session实例
     * @return Session
     */
    public static function instance(){

        // 实现单例模式
        if(!(self::$_instance instanceof self)){
            self::$_instance = new self();
        }
        return self::$_instance;

    }

    /**
     * 设置session
     * @param $name
     * @param null $value
     * @param int $expire
     * @return bool
     */
    public function set($name, $value = null, $expire = 0){

        $expiration = $expire ? $expire + time() : 0;
        // 如果$name,$value都是字符串时直接设置
        if(is_string($name) && !empty($value)){
            $record = [
                'name' => $name,
                'value' => $value,
                'expire' => $expiration
            ];
            self::$session[$name] = $record;
        }
        // 如果$name是数组时循环设置
        if(is_array($name)){
            foreach($name as $key=>$val){
                $record = [
                    'name' => $key,
                    'value' => $val,
                    'expire' => $expiration
                ];
                self::$session[$key] = $record;
            }
        }
        // 同步session
        $this->cogradient();
        // 返回值为空
        return true;

    }

    /**
     * 销毁整个session或删除session中的对应项
     * @param null $name
     * @return bool|int
     */
    public function delete($name = null){

        // 如果$name为null就直接销毁
        if(is_null($name)){
            return $this->destroy();
        }
        // 如果$name为字符串就进行删除
        if(is_string($name)){
            // $name对应项目是否存在，如存在就删除$name对应的项
            if(isset(self::$session[$name])){
                unset(self::$session[$name]);
                return true;
            }
        }
        // 同步session
        $this->cogradient();
        // 返回值为空
        return false;

    }

    /**
     * 更新session
     * @param $name
     * @param null $value
     * @param int $expire
     * @return bool
     */
    public function update($name, $value = null, $expire = 0){
        return $this->set($name, $value, $expire);
    }

    /**
     * 获取session
     * @param null $name
     * @return array|bool|null
     */
    public function get($name = null){

        // 如果是字符串，并且$name对应项存在时返回$name对应项
        if(is_string($name) && isset(self::$session[$name])){
            $record = self::$session[$name];
            if(isset($record['name']) && $name == $record['name'] && ($record['expire'] >= time() || $record['expire'] == 0)){
                return $record['value'];
            }
        }
        if(is_null($name)){
            return self::$session;
        }
        return false;

    }

    /**
     * 销毁整个session
     * @return int 返回状态
     */
    public function destroy(){

        // 如果$_SESSION不为空，就把它设置为空数组
        if(!empty(self::$session)){
            self::$session = [];
            $this->cogradient();
        }
        // 销毁整个session
        session_destroy();
        /*
         * PHP_SESSION_DISABLED（0） 会话是被禁用的。
         * PHP_SESSION_NONE（1） 会话是启用的，但不存在当前会话。
         * PHP_SESSION_ACTIVE（2） 会话是启用的，而且存在当前会话。
         */
        return session_status();

    }

    /**
     * 同步session
     * @return bool
     */
    private function cogradient(){

        if(!isset($_SESSION[md5('luoPhp')])){
            $_SESSION[md5('luoPhp')] = [];
        }

        if($_SESSION[md5('luoPhp')] !== self::$session){
            $_SESSION[md5('luoPhp')] = self::$session;
            return true;
        }
        return false;

    }

    /**
     * 析构
     */
    public function __destruct()
    {

        // TODO: Implement __destruct() method.
        $_SESSION[md5('luoPhp')] = self::$session;

    }

}
